package com.sicau.utils;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.sicau.constants.LanguageConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

@Slf4j
public class YouDaoTranslation {

    private final RestTemplate restTemplate;
    private final String YOUDAO_URL;
    private final String APP_KEY;
    private final String APP_SECRET;
    private String from;
    private String to;

    public YouDaoTranslation(RestTemplate restTemplate, String YOUDAO_URL, String APP_KEY, String APP_SECRET) {
        this(restTemplate, YOUDAO_URL, APP_KEY, APP_SECRET, LanguageConstants.AUTO, LanguageConstants.CHINESE_SIMPLIFIED);
    }

    public YouDaoTranslation(RestTemplate restTemplate, String YOUDAO_URL, String APP_KEY, String APP_SECRET, String from, String to) {
        this.restTemplate = restTemplate;
        this.YOUDAO_URL = YOUDAO_URL;
        this.APP_KEY = APP_KEY;
        this.APP_SECRET = APP_SECRET;
        this.from = from;
        this.to = to;
    }

    /**
     * 翻译
     * @param query
     * @return
     */
    public String translate(String query) {
        log.info("query: {}", query);
        log.info("from: {}",  from);
        log.info("to: {}",  to);
        // 固定参数
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("from", this.from);
        params.add("to", this.to);
        params.add("signType", "v3");
        // 临时参数
        String curtime = String.valueOf(System.currentTimeMillis() / 1000);
        String salt = String.valueOf(System.currentTimeMillis());
        params.add("curtime", curtime);
        String signStr = APP_KEY + truncate(query) + salt + curtime + APP_SECRET;
        String sign = getDigest(signStr);
        params.add("appKey", APP_KEY);
        params.add("q", query);
        params.add("salt", salt);
        params.add("sign", sign);
        // 设置请求头为表单格式
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // 封装请求参数
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
        // 发送请求，响应结果
        String response = restTemplate.postForObject(YOUDAO_URL, request, String.class);
        // 解析结果
        JSONObject jsonObject = JSONUtil.parseObj(response);
        Object[] translations = jsonObject.getJSONArray("translation").toArray();
        if (translations.length == 0) {
            return "";
        }
        String s = translations[0].toString();
        log.info("result: {}", s);
        return s;
    }

    /**
     * 生成加密字段
     */
    private String getDigest(String string) {
        if (string == null) {
            return null;
        }
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        byte[] btInadd = string.getBytes(StandardCharsets.UTF_8);
        try {
            MessageDigest mdInst = MessageDigest.getInstance("SHA-256");
            mdInst.update(btInadd);
            byte[] md = mdInst.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (byte byte0 : md) {
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
    }

    private String truncate(String q) {
        if (q == null) {
            return null;
        }
        int len = q.length();
        String result;
        return len <= 20 ? q : (q.substring(0, 10) + len + q.substring(len - 10, len));
    }
}
